package com.gitee.wsl.doc.prosemirror.plugin

import com.gitee.wsl.doc.prosemirror.plugin.PluginKey.Companion.createKey
import com.gitee.wsl.doc.prosemirror.state.EditorState
import com.gitee.wsl.doc.prosemirror.state.Transaction

/**
 * Plugins bundle functionality that can be added to an editor.
 * They are part of the [editor state](#state.EditorState) and
 * may influence that state and the view that contains it.
 */
open class Plugin<PluginState>(
    // The plugin's [spec object](#state.PluginSpec).
    pluginSpec: PluginSpec<PluginState>
) {

    open val spec: PluginSpec<PluginState> = pluginSpec

    internal val key: String = pluginSpec.key?.key ?: createKey("plugin")

    /**
     * Allows the plugin to append another transaction to be applied
     * after the given array of transactions. When another plugin
     * appends a transaction after this was called, it is called again
     * with the new state and new transactions—but only the new
     * transactions, i.e. it won't be passed transactions that it
     * already saw.
     */
    open val appendTransaction: ((List<Transaction>, oldState:EditorState, newState:EditorState) -> Transaction?)? = null

    /**
     * When present, this will be called before a transaction is
     * applied by the state, allowing the plugin to cancel it (by
     * returning false).
     */
    open val filterTransaction: ((tr: Transaction, state: EditorState) -> Boolean)? = null

    // Extract the plugin's state field from an editor state.
    fun getState(state: EditorState): PluginState? {
        return state.stateFields[key] as PluginState?
    }

    companion object{

    }
}

fun<PluginState> Plugin<PluginState>.filterTransaction(tr: Transaction, state: EditorState):Boolean{
    filterTransaction?:return true
    return filterTransaction!!.invoke(tr, state)
}